package main

import (
	"fmt"
	"strconv"
	"sync"
)

/*
sync.Map介绍

	1. Go语言中内置的map不是并发安全的，开启少量几个goroutine的时候可能没什么问题，当并发多了之后执行上面的代码就会报fatal error:
	   concurrent map writes错误；
	2. Go语言的sync包中提供了一个开箱即用的并发安全版map–sync.Map。开箱即用表示不用像内置的map一样使用make函数初始化就能直接使用。
	   同时sync.Map内置了诸如Store、Load、LoadOrStore、Delete、Range等操作方法
*/

var m = make(map[string]int)
var syncMap = sync.Map{}

func main() {

	/*
		一. Go语言中内置的map不是并发安全的
	*/
	//wg := sync.WaitGroup{}
	//for i := 0; i < 20; i++ {
	//	wg.Add(1)
	//	go func(n int) {
	//		key := strconv.Itoa(n)
	//		set(key, n)
	//		fmt.Printf("k=:%v,v:=%v\n", key, get(key))
	//		wg.Done()
	//	}(i)
	//}
	//wg.Wait()
	//fmt.Println("main over")

	/*
		二. 并发安全版map–sync.Map
	*/
	wg := sync.WaitGroup{}
	for i := 0; i < 20; i++ {
		wg.Add(1)
		go func(n int) {
			key := strconv.Itoa(n)
			syncMap.Store(key, n)
			value, _ := syncMap.Load(key)
			fmt.Printf("k=:%v,v:=%v\n", key, value)
			wg.Done()
		}(i)
	}
	wg.Wait()
	fmt.Println("main over")
}

func get(key string) int {

	return m[key]
}

func set(key string, value int) {

	m[key] = value
}
